<template>
  <div class="chart-container" style="width: 1400px; height: 80%;" :key="componentKey">
    <!-- 添加导出按钮 -->
    <div class="export-button">
      <el-button type="primary" @click="exportAsPNG" size="large">
        Download
      </el-button>
    </div>
    <!-- SNV选择框 -->
    <div class="snv-selector">
      <el-select
        v-model="selectedSnv"
        @change="getdata"
        placeholder="Select SNV"
        size="large"
        style="width: 200px;"
      >
        <el-option
          v-for="snv in snvOptions"
          :key="snv"
          :label="snv"
          :value="snv"
        />
      </el-select>
    </div>

    <!-- 添加 v-loading 和加载文本 -->
    <div 
      class="gene-map" 
      v-loading="data.svgloading"
      element-loading-text="Loading data..."
      element-loading-background="rgba(255, 255, 255, 0.9)"
    >
      <!-- 图例 -->
      <div class="legend">
        <div v-for="(color, type) in typeColors" :key="type"
             class="legend-item"
             @click="toggleVisibility(type)"
             :class="{ 'legend-item-hidden': !visibleTypes[type] }"
             style="cursor: pointer;">
          <span class="legend-color" :style="{
            backgroundColor: type === 'anchor' ? color : 'transparent',
            borderLeft: type !== 'anchor' ? `4px solid ${color}` : 'none',
            width: type === 'anchor' ? '24px' : '4px',
            opacity: visibleTypes[type] ? 1 : 0.3
          }">
          </span>
          <span v-if="type === 'cpg'">CpG</span>
          <span v-else class="legend-label">{{ type.toUpperCase() }}</span>
        </div>
      </div>

      <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="800" height="200">
        <!-- 染色体名称 -->
        <text
          x="50"
          y="80"
          font-size="16"
          font-weight="bold"
          fill="#333"
        >{{ data.chromosomeName }}</text>

        <!-- 染色体主体 -->
        <rect x="50" y="100" width="700" height="30" fill="#FFFFFF" stroke="#333" stroke-width="1"/>

        <!-- 所有可视化元素的容器 -->
        <g class="visualization-layer">
          <!-- Anchor节点 -->
          <g v-if="visibleTypes['anchor']">
            <g v-for="(item, index) in filteredData('anchor')" :key="`anchor-${index}`" 
               class="gene-marker"
               @mouseenter="showTooltip(item, $event)"
               @mouseleave="hideTooltip">
              <rect
                :x="item.position - 5"
                y="90"
                width="10"
                height="50"
                :fill="typeColors[item.type]"
                style="cursor: pointer"
              />
            </g>

            <!-- 连接线 -->
            <path
              v-for="(connection, index) in data.connections"
              :key="`connection-${index}`"
              :d="connection.path"
              fill="none"
              stroke="#666"
              stroke-width="1.5"
              opacity="0.7"
            />
          </g>

          <!-- Gene节点 -->
          <g v-if="visibleTypes['gene']">
            <g v-for="(item, index) in filteredData('gene')" :key="`gene-${index}`"
               class="gene-marker"
               @mouseenter="showTooltip(item, $event)"
               @mouseleave="hideTooltip">
              <line
                :x1="item.position"
                :y1="95"
                :x2="item.position"
                :y2="135"
                :stroke="typeColors[item.type]"
                stroke-width="2"
              />
              <rect
                :x="item.position - 5"
                y="90"
                width="10"
                height="50"
                fill="transparent"
                style="cursor: pointer"
              />
            </g>
          </g>

          <!-- CpG节点 -->
          <g v-if="visibleTypes['cpg']">
            <g v-for="(item, index) in filteredData('cpg')" :key="`cpg-${index}`"
               class="gene-marker"
               @mouseenter="showTooltip(item, $event)"
               @mouseleave="hideTooltip">
              <line
                :x1="item.position"
                :y1="95"
                :x2="item.position"
                :y2="135"
                :stroke="typeColors[item.type]"
                stroke-width="2"
              />
              <rect
                :x="item.position - 5"
                y="90"
                width="10"
                height="50"
                fill="transparent"
                style="cursor: pointer"
              />
            </g>
          </g>

          <!-- SNV节点 -->
          <g v-if="visibleTypes['snv']">
            <g v-for="(item, index) in filteredData('snv')" :key="`snv-${index}`"
               class="gene-marker"
               @mouseenter="showTooltip(item, $event)"
               @mouseleave="hideTooltip">
              <line
                :x1="item.position"
                :y1="95"
                :x2="item.position"
                :y2="135"
                :stroke="typeColors[item.type]"
                stroke-width="2"
              />
              <rect
                :x="item.position - 5"
                y="90"
                width="10"
                height="50"
                fill="transparent"
                style="cursor: pointer"
              />
            </g>
          </g>
        </g>

        <!-- 刻度尺 -->
        <g class="axis">
          <line x1="50" y1="140" x2="750" y2="140" stroke="#666" stroke-width="1"/>
          <g v-for="(tick, index) in data.ticks" :key="`tick-${index}`">
            <line
              :x1="tick.x"
              y1="140"
              :x2="tick.x"
              y2="145"
              stroke="#666"
              stroke-width="1"
            />
            <text
              :x="tick.x"
              y="160"
              text-anchor="middle"
              font-size="10"
            >{{ tick.label }}</text>
          </g>
        </g>
      </svg>

      <!-- Tooltip -->
      <div
        v-if="tooltip.show"
        class="tooltip"
        :style="{
          left: tooltip.x + 'px',
          top: `${tooltip.y - 80}px`
        }"
      >
        <div class="tooltip-content">
          <div><strong>Type:</strong> {{ tooltip.item?.type }}</div>
          <div><strong>Name:</strong> {{ tooltip.item?.name }}</div>
          <div><strong>Start:</strong> {{ tooltip.item?.start }}</div>
          <div><strong>End:</strong> {{ tooltip.item?.end }}</div>
          <!-- <div><strong>Sample ID:</strong> {{ tooltip.item?.sampleId }}</div> -->
        </div>
      </div>
    </div>
  </div>
   
</template>

<script setup>
import { ref, computed, watch, onMounted, nextTick, markRaw } from 'vue';
import {useRoute} from "vue-router";
import { reactive } from '@vue/reactivity';
import axios from 'axios';
import { request } from '@/api/request';
import html2canvas from 'html2canvas';
const route = useRoute()
const props = defineProps({
  snvList: {
    type: String,
    default: ''
  }
});

// 类型颜色映射
const typeColors = {
  gene: '#E41A1C',    // 鲜艳的红色，用于基因
  snv: '#377EB8',     // 明亮的蓝色，用于SNV
  cpg: '#4DAF4A',     // 鲜艳的绿色，用于CpG位点
  anchor: 'rgba(152, 78, 163, 0.3)'   // 浅紫色，用于锚点
};

// 添加显示状态控制
const visibleTypes = ref({
  gene: true,
  snv: true,
  cpg: true,
  anchor: true
});

const selectedSnv = ref('');
const tooltip = ref({
  show: false,
  x: 0,
  y: 0,
  item: null
});

const data = reactive({
  analysisData: [],
  anchorData: [],
  processedData: [],
  connections: [],
  ticks: [],
  chromosomeName: '',
  svgloading: false
});

const componentKey = ref(0);

// 过滤数据的计算属性
const filteredData = (type) => {
  return data.processedData.filter(item => item.type === type);
};

// 生成刻度
const getTicks = (processedData) => {
  if (!processedData || processedData.length === 0) {
    return [];
  }
  const minPosition = Math.min(...processedData.map(item => parseInt(item.start)));
  const maxPosition = Math.max(...processedData.map(item => parseInt(item.end)));
  const tickCount = 5;
  const interval = (maxPosition - minPosition) / (tickCount - 1);

  return Array.from({ length: tickCount }, (_, i) => ({
    x: 50 + (i * 700 / (tickCount - 1)),
    label: Math.round(minPosition + i * interval).toLocaleString()
  }));
};

// 数据处理函数
const processAnalysisData = (inputData) => {
  if (!inputData || !Array.isArray(inputData)) {
    return [];
  }

  const processed = [];
  const seen = new Set();

  // 处理主数据
  inputData.forEach(item => {
    // 处理基因
    const geneKey = `gene-${item.gene}-${item.geneStart}-${item.geneEnd}`;
    if (!seen.has(geneKey)) {
      processed.push({
        name: item.gene,
        type: 'gene',
        start: item.geneStart,
        end: item.geneEnd,
        chr: item.chr,
        sampleId: item.sampleId
      });
      seen.add(geneKey);
    }

    // 处理SNV
    const snvKey = `snv-${item.snv}-${item.snvPos}`;
    if (!seen.has(snvKey)) {
      processed.push({
        name: item.snv,
        type: 'snv',
        start: item.snvPos,
        end: item.snvPos,
        chr: item.chr,
        sampleId: item.sampleId
      });
      seen.add(snvKey);
    }

    // 处理CpG
    const cpgKey = `cpg-${item.cpgPos}`;
    if (!seen.has(cpgKey)) {
      processed.push({
        name: 'cpg',
        type: 'cpg',
        start: item.cpgPos,
        end: item.cpgPos,
        chr: item.chr,
        sampleId: item.sampleId
      });
      seen.add(cpgKey);
    }
  });

  // 处理锚点数据
  if (data.anchorData && Array.isArray(data.anchorData)) {
    // 按sampleId分组的锚点对
    const anchorPairs = {};
    
    data.anchorData.forEach(anchor => {
      const key = anchor.sampleId;
      if (!anchorPairs[key]) {
        anchorPairs[key] = {};
      }
      anchorPairs[key][anchor.name] = anchor;
    });

    // 处理每对锚点
    Object.values(anchorPairs).forEach(pair => {
      if (pair.anchor1) {
        const anchor1Key = `anchor-${pair.anchor1.sampleId}-${pair.anchor1.start}`;
        if (!seen.has(anchor1Key)) {
          processed.push({
            name: 'anchor1',
            type: 'anchor',
            start: pair.anchor1.start,
            end: pair.anchor1.end,
            chr: pair.anchor1.chr,
            sampleId: pair.anchor1.sampleId
          });
          seen.add(anchor1Key);
        }
      }
      
      if (pair.anchor2) {
        const anchor2Key = `anchor-${pair.anchor2.sampleId}-${pair.anchor2.start}`;
        if (!seen.has(anchor2Key)) {
          processed.push({
            name: 'anchor2',
            type: 'anchor',
            start: pair.anchor2.start,
            end: pair.anchor2.end,
            chr: pair.anchor2.chr,
            sampleId: pair.anchor2.sampleId
          });
          seen.add(anchor2Key);
        }
      }
    });
  }

  return processed;
};

// 处理位置和比例
const processPositions = (processedData) => {
  if (!processedData || processedData.length === 0) return [];
  
  const minPosition = Math.min(...processedData.map(item => parseInt(item.start)));
  const maxPosition = Math.max(...processedData.map(item => parseInt(item.end)));
  const scale = 700 / (maxPosition - minPosition);

  return processedData.map(item => ({
    ...item,
    position: 50 + (parseInt(item.start) - minPosition) * scale
  }));
};

// 处理连接线
const processConnections = (processedData) => {
  const result = [];
  const groupedData = {};

  processedData.forEach(item => {
    if (item.type === 'anchor' && item.name) {
      if (!groupedData[item.sampleId]) {
        groupedData[item.sampleId] = {};
      }
      if (item.name === 'anchor1') {
        groupedData[item.sampleId].anchor1 = item;
      } else if (item.name === 'anchor2') {
        groupedData[item.sampleId].anchor2 = item;
      }
    }
  });

  Object.values(groupedData).forEach(anchors => {
    if (anchors.anchor1 && anchors.anchor2) {
      const { anchor1, anchor2 } = anchors;
      const path = `M ${anchor1.position} 90 Q ${(anchor1.position + anchor2.position) / 2} 45, ${anchor2.position} 90`;
      result.push({ path });
    }
  });

  return result;
};

// 修改获取数据的函数
const getdata = async () => {
  try {
    data.svgloading = true;
    let tissue = JSON.parse(route.query.form).tissue
    console.log(tissue)
    const res = await request.get(`/analysis2/plot`, {snv: props.snvList[0],tissue});
    
    // 确保数据存在
    if (res.data) {
      data.analysisData = res.data.mainData || [];
      data.anchorData = res.data.anchors || [];

      // 立即处理数据
      const processed = processAnalysisData(data.analysisData);
      data.processedData = processPositions(processed);
      data.connections = processConnections(data.processedData);
      data.ticks = getTicks(data.processedData);
      data.chromosomeName = processed.length > 0 ? processed[0].chr : '';
      
      // 强制更新视图
      nextTick(() => {
        // 先将所有类型设置为false
        Object.keys(visibleTypes.value).forEach(key => {
          visibleTypes.value[key] = false;
        });
        
        // 短暂延时后重新设置为true
        setTimeout(() => {
          Object.keys(visibleTypes.value).forEach(key => {
            visibleTypes.value[key] = true;
          });
        }, 100);
      });

      // 在数据加载完成后更新key
      nextTick(() => {
        componentKey.value += 1;
      });
    }
  } catch (error) {
    console.error("获取数据失败:", error);
    data.processedData = [];
    data.connections = [];
    data.ticks = [];
  } finally {
    data.svgloading = false;
  }
};

// SNV选择相关
const snvOptions = computed(() => {
  if (!props.snvList) return [];
  return props.snvList;
});

// 其他方法
const showTooltip = (item, event) => {
  const rect = event.target.getBoundingClientRect();

  tooltip.value = {
    show: true,
    x: rect.left + (rect.width / 2),
    y: rect.top - 45,
    item
  };
};

const hideTooltip = () => {
  tooltip.value.show = false;
};

const toggleVisibility = (type) => {
  visibleTypes.value[type] = !visibleTypes.value[type];
};

// 修改watch
watch(() => props.snvList, (newVal) => {
  if (newVal && Array.isArray(newVal) && newVal.length > 0) {
    selectedSnv.value = newVal[0];
    getdata();
  }
}, { immediate: true, deep: true });

// 添加染色体名称的计算属性
const chromosomeName = () => {
  if (data.processedData && data.processedData.length > 0) {
    const firstItem = data.processedData[0];
    console.log("染色体名称:", firstItem.chr);
    return firstItem.chr;
  }
  return '';
};

// 添加导出PNG的方法
const exportAsPNG = async () => {
  try {
    // 获取SVG元素和图例元素
    const svgElement = document.querySelector('.gene-map svg');
    const legendElement = document.querySelector('.gene-map .legend');
    if (!svgElement || !legendElement) return;

    // 创建一个新的canvas
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // 设置canvas大小，考虑到SVG的缩放(1.5)和额外的空间给图例
    canvas.width = svgElement.width.baseVal.value * 1.5;
    canvas.height = (svgElement.height.baseVal.value * 1.5) + 100; // 额外100px给图例

    // 设置白色背景
    ctx.fillStyle = '#FFFFFF';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 将SVG转换为图片
    const svgData = new XMLSerializer().serializeToString(svgElement);
    const svgBlob = new Blob([svgData], { type: 'image/svg+xml;charset=utf-8' });
    const svgUrl = URL.createObjectURL(svgBlob);

    // 创建图片对象来加载SVG
    const img = new Image();
    img.onload = async () => {
      // 绘制SVG
      ctx.drawImage(img, 0, 50, canvas.width, canvas.height - 100);

      // 使用html2canvas单独处理图例
      try {
        const legendCanvas = await html2canvas(legendElement, {
          backgroundColor: '#FFFFFF',
          scale: 2,
          logging: false
        });

        // 在顶部绘制图例
        ctx.drawImage(legendCanvas, 
          canvas.width / 2 - legendCanvas.width / 4, // 居中
          0, // 顶部
          legendCanvas.width / 2, 
          legendCanvas.height / 2
        );

        // 创建下载链接
        const a = document.createElement('a');
        a.download = `gene_map_${Date.now()}.png`;
        a.href = canvas.toDataURL('image/png');
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
      } catch (error) {
        console.error('处理图例失败:', error);
      }

      // 清理URL对象
      URL.revokeObjectURL(svgUrl);
    };

    img.src = svgUrl;
  } catch (error) {
    console.error('导出图片失败:', error);
  }
};

onMounted(() => {
  selectedSnv.value = snvOptions.value[0];
});
</script>

<style scoped>
.chart-container {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.gene-map {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 20px;
  min-height: 300px;
  background-color: #FFFFFF;
  padding: 20px;
  border-radius: 8px;
}

.gene-map svg {
  width: 800px;
  height: 200px;
  transform: scale(1.5);
  background-color: #FFFFFF;
}

.gene-marker {
  transition: all 0.3s;
}

.gene-marker:hover {
  opacity: 0.8;
  filter: brightness(1.2);
}

.tooltip {
  position: fixed;
  z-index: 1000;
  pointer-events: none;
  transform: translateX(-50%);
}

.tooltip-content {
  background: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 8px 12px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  box-shadow: 0 2px 4px rgba(0,0,0,0.2);
  min-width: 150px;
}

.tooltip-content::after {
  content: '';
  position: absolute;
  bottom: -6px;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 6px solid rgba(0, 0, 0, 0.8);
}

.tooltip-content div {
  margin: 4px 0;
  line-height: 1.4;
}

text {
  font-family: Arial, sans-serif;
  dominant-baseline: middle;
}

.legend {
  display: flex;
  gap: 25px;
  padding: 15px;
  background: #ffffff;
  border-radius: 6px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
  margin-bottom: -20px;
  z-index: 100;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 80px;
  padding: 5px 10px;
  border-radius: 4px;
  transition: all 0.3s ease;
}

.legend-item:hover {
  background-color: rgba(0, 0, 0, 0.05);
}

.legend-item-hidden {
  opacity: 0.5;
}

.legend-color {
  height: 24px;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
  display: inline-block;
}

.legend-label {
  font-size: 13px;
  color: #444;
  font-weight: 500;
  white-space: nowrap;
}

/* SNV选择器样式 */
.snv-selector {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 100;
  background-color: white;
  padding: 10px;
  border-radius: 4px;
  /* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
}

/* 添加加载动画相关样式 */
:deep(.el-loading-mask) {
  border-radius: 4px;
}

:deep(.el-loading-text) {
  font-size: 14px;
  color: #409EFF;
}

/* 添加导出按钮样式 */
.export-button {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 100;
}
</style>
